package com.joolun.mall.service.impl;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joolun.common.core.domain.entity.SysDictData;
import com.joolun.common.exception.CustomException;
import com.joolun.common.utils.DateUtils;
import com.joolun.common.utils.SecurityUtils;
import com.joolun.common.utils.StringUtils;
import com.joolun.mall.constant.DicType;
import com.joolun.mall.domain.dto.ChainOrderDetailDTO;
import com.joolun.mall.domain.vo.ChainOrderDetailVO;
import com.joolun.mall.domain.vo.ChainPlanReserveOrderError;
import com.joolun.mall.entity.*;
import com.joolun.mall.mapper.*;
import com.joolun.mall.service.IChainPlanService;
import com.joolun.mall.service.IChainService;
import com.joolun.system.service.ISysDictDataService;
import com.joolun.system.service.ISysDictTypeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.joolun.mall.service.IChainPlanReserveOrderService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 接龙计划预留名单Service业务层处理
 * 
 * @author www.joolun.com
 * @date 2025-08-04
 */
@Service
public class ChainPlanReserveOrderServiceImpl extends ServiceImpl<ChainPlanReserveOrderMapper, ChainPlanReserveOrder> implements IChainPlanReserveOrderService
{
    @Autowired
    private ISysDictDataService dictDataService;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private ChainPlanReserveOrderMapper chainPlanReserveOrderMapper;

    @Autowired
    private ChainMapper chainMapper;

    @Autowired
    private ChainDetailMapper chainDetailMapper;

    @Autowired
    private IChainService chainService;

    @Autowired
    private IChainPlanService chainPlanService;

    @Autowired
    private ChainPlanMapper chainPlanMapper;

    @Autowired
    private ChainOrderMapper orderMapper;


    @Autowired
    private ChainOrderDetailMapper orderDetailMapper;

    @Autowired
    private IChainPlanReserveOrderService chainPlanReserveOrderService;

    @Autowired
    private ChainTbWdtRelMapper chainTbWdtRelMapper;

//    @Autowired
//    private IChainPlanService planService;

    @Transactional
    @Override
    public boolean syncReserve(Long planId) {
        List<Chain> chains = chainMapper.selectList(Wrappers.<Chain>lambdaQuery().eq(Chain::getPlanId, planId).eq(Chain::getDelFlag, "0"));
        if(CollectionUtil.isNotEmpty(chains)){
            List<Long> chainIds = chains.stream().map(Chain::getId).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(chainIds)){
                ChainOrderDetailDTO dto = new ChainOrderDetailDTO();
                dto.setChainIds(chainIds);
//                dto.setOrderState(0);
                List<ChainOrderDetailVO> chainOrderDetailVOS = orderDetailMapper.selectOrderDetails(dto);
                List<ChainPlanReserveOrder> reserveOrders = new ArrayList<>();
                chainOrderDetailVOS.forEach(e ->{
                    ChainPlanReserveOrder reserveOrder = new ChainPlanReserveOrder();
                    reserveOrder.setPlanId(planId);
                    reserveOrder.setTbUserId(e.getTbUserId());
                    reserveOrder.setWdtEncodeUserId(e.getWdtEncodeUserId());
                    reserveOrder.setSpuName(e.getSpuName());
                    reserveOrder.setSkuCode(e.getSkuCode());
                    reserveOrder.setIsExceed(e.getIsExceed());
                    reserveOrder.setBrandId(e.getBrandId());
                    reserveOrder.setSpecification(e.getSpecification());
                    reserveOrder.setCreateTime(e.getCreateTime());
                    reserveOrder.setVipType(e.getVipType());
                    reserveOrder.setVipTypeValue(e.getVipTypeValue());
                    reserveOrder.setCount(1L);
                    reserveOrders.add(reserveOrder);
                });

                chainPlanReserveOrderService.saveBatch(reserveOrders, 5000);
            }
            //更新为已预留
            ChainPlan chainPlan = new ChainPlan();
            chainPlan.setId(planId);
            chainPlan.setReserveStatus("1");
            chainPlanService.updateById(chainPlan);
        }
        return true;
    }

    @Transactional
    @Override
    public List<ChainPlanReserveOrderError> importData(List<ChainPlanReserveOrder> datas) {
        int rowNum = 0;

        List<ChainPlanReserveOrderError> errorList = new ArrayList<>();
        Map<String, ChainDetail> chainDetailGroup = null;
        Map<Long, Chain> chainGroup = null;
        ChainPlan chainPlan = null;
        for (ChainPlanReserveOrder dto : datas) {
            rowNum = rowNum + 1;
            ChainPlanReserveOrderError errorVo = checkBasicInfo(dto);

            //只查一次
            if(rowNum == 1){
                List<Chain> chains = chainMapper.selectList(Wrappers.<Chain>lambdaQuery().eq(Chain::getPlanId, dto.getPlanId()).eq(Chain::getDelFlag, "0"));
                if(CollectionUtil.isEmpty(chains)){
                    errorVo.setError(errorVo.getError() + "该计划下不存在接龙链接 ");
                    errorList.add(errorVo);
                    continue;
                }
                chainGroup = chains.stream().collect(Collectors.toMap(
                        Chain::getId,
                        Function.identity(),
                        (e, r) -> r
                ));


                chainPlan = chainPlanMapper.selectById(dto.getPlanId());

                List<Long> chainIds = chains.stream().map(Chain::getId).collect(Collectors.toList());
                List<ChainDetail> chainDetails = chainDetailMapper.selectList(Wrappers.<ChainDetail>lambdaQuery().in(ChainDetail::getChainId, chainIds).eq(ChainDetail::getDelFlag, "0"));
                if(CollectionUtil.isEmpty(chainDetails)){
                    errorVo.setError(errorVo.getError() + "该计划下不存在接龙商家编码:" + dto.getSkuCode() + " ");
                    errorList.add(errorVo);
                    continue;
                }

                dto.setBrandId(chainPlan.getBrandId());
                chainDetailGroup = chainDetails.stream().collect(Collectors.toMap(
                        ChainDetail::getSkuCode,
                        Function.identity(),
                        (e, r) -> r
                ));
            }
            if(StringUtils.isNotEmpty(errorVo.getError())){
                errorList.add(errorVo);
                continue;
            }

            if (chainDetailGroup != null && !chainDetailGroup.containsKey(dto.getSkuCode())) {
                errorVo.setError(errorVo.getError() + "该计划下不存在接龙商家编码:" + dto.getSkuCode() + " ");
                errorList.add(errorVo);
                continue;
            }

            ChainDetail chainDetail = chainDetailGroup.get(dto.getSkuCode());
            dto.setSpuName(chainGroup.get(chainDetail.getChainId()).getName() + "-"+ chainDetail.getSpuName());
            dto.setSpecification(StringUtils.trim(chainDetail.getColor()) + StringUtils.trim(chainDetail.getSize()));
            dto.setBrandId(chainPlan.getBrandId());
            if(!checkTbUserIdAndWdtId(dto)){
                errorVo.setError(errorVo.getError() + "淘宝账号和旺店通加密ID不匹配 ");
                errorList.add(errorVo);
                continue;
            }

            List<ChainPlanReserveOrder> chainPlanReserveOrders = chainPlanReserveOrderMapper.selectList(Wrappers.<ChainPlanReserveOrder>lambdaQuery()
                    .eq(ChainPlanReserveOrder::getSkuCode, dto.getSkuCode())
                    .eq(ChainPlanReserveOrder::getPlanId, dto.getPlanId())
                    .eq(ChainPlanReserveOrder::getTbUserId, dto.getTbUserId())
                    .eq(ChainPlanReserveOrder::getWdtEncodeUserId, dto.getWdtEncodeUserId())
                    .eq(ChainPlanReserveOrder::getDelFlag, "0")
            );

            //处理删除
            if(dto.getCount() == 0){
                if(CollectionUtil.isEmpty(chainPlanReserveOrders)){
                    errorVo.setError(errorVo.getError() +"删除的数据不存在 ");
                    errorList.add(errorVo);
                    continue;
                }else{
                    chainPlanReserveOrderMapper.deleteById(chainPlanReserveOrders.get(0).getId());
                }
            }else{
                if(CollectionUtil.isEmpty(chainPlanReserveOrders)){
                    dto.setCreateTime(DateUtils.getNowDate());
                    chainPlanReserveOrderMapper.insert(dto);
                }else{
                    dto.setUpdateBy(SecurityUtils.getUsername());
                    dto.setUpdateTime(DateUtils.getNowDate());
                    dto.setId(chainPlanReserveOrders.get(0).getId());
                    chainPlanReserveOrderMapper.updateById(dto);
                }
            }
            if(StringUtils.isNotEmpty(errorVo.getError())){
                errorList.add(errorVo);
            }
        }
        return errorList;
    }

    // 品牌 淘宝账号 旺店通加密ID
    private boolean checkTbUserIdAndWdtId(ChainPlanReserveOrder dto) {
        List<ChainTbWdtRel> tbWdtRels = chainTbWdtRelMapper.selectList(Wrappers.<ChainTbWdtRel>lambdaQuery()
                .eq(ChainTbWdtRel::getDelFlag, "0")
                .eq(ChainTbWdtRel::getBrandId, dto.getBrandId())
                .and(e ->
                        e.eq(ChainTbWdtRel::getTbUserId, dto.getTbUserId())
                                .or().eq(ChainTbWdtRel::getWdtEncodeUserId, dto.getWdtEncodeUserId()
                                )
                ));
        if (CollectionUtil.isNotEmpty(tbWdtRels)) {
            // 查找第一个不匹配的元素
            Optional<ChainTbWdtRel> first = tbWdtRels.stream()
                    .filter(Objects::nonNull)
                    .filter(item -> !Objects.equals(item.getTbUserId(), dto.getTbUserId())
                            || !Objects.equals(item.getWdtEncodeUserId(), dto.getWdtEncodeUserId()))
                    .findFirst();
            return !first.isPresent();

        }
        return true;
    }

    private ChainPlanReserveOrderError checkBasicInfo(ChainPlanReserveOrder dto) {
        ChainPlanReserveOrderError errorVo = new ChainPlanReserveOrderError();
        BeanUtils.copyProperties(dto, errorVo);
        String errorMsg = "";
        if(StringUtils.trim(errorVo.getTbUserId()).isEmpty()){
            errorMsg = errorMsg + "淘宝账号(旺旺id)不能为空 ";
        }
        if(StringUtils.trim(errorVo.getWdtEncodeUserId()).isEmpty()){
            errorMsg = errorMsg + "旺店通加密ID不能为空 ";
        }
        if(StringUtils.trim(errorVo.getSkuCode()).isEmpty()){
            errorMsg = errorMsg + "商家编码不能为空 ";
        }
        List<SysDictData> sysDictData = dictTypeService.selectDictDataByType(DicType.DICT_TYPE_VIP_TYPE);
        Map<String, String> vipMap = sysDictData.stream().collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));

        if(StringUtils.trim(errorVo.getVipTypeValue()).isEmpty()){
            errorMsg = errorMsg + "发货VIP等级不能为空 ";
        }else{
            if (vipMap.containsKey(errorVo.getVipTypeValue())){
                dto.setVipType(vipMap.get(errorVo.getVipTypeValue()));
            }else{
                errorMsg = errorMsg + "发货VIP等级不存在 ";
            }
        }
        if(Objects.isNull(errorVo.getCount())){
            errorMsg = errorMsg + "数量不能为空 ";
        }
        errorVo.setError(errorMsg);
        return errorVo;
    }

    /**
     * 查询接龙计划预留名单
     * 
     * @param id 接龙计划预留名单ID
     * @return 接龙计划预留名单
     */
    @Override
    public ChainPlanReserveOrder selectChainPlanReserveOrderById(Long id)
    {
        return chainPlanReserveOrderMapper.selectChainPlanReserveOrderById(id);
    }

    /**
     * 查询接龙计划预留名单列表
     * 
     * @param chainPlanReserveOrder 接龙计划预留名单
     * @return 接龙计划预留名单
     */
    @Override
    public List<ChainPlanReserveOrder> selectChainPlanReserveOrderList(ChainPlanReserveOrder chainPlanReserveOrder)
    {
        return chainPlanReserveOrderMapper.selectChainPlanReserveOrderList(chainPlanReserveOrder);
    }

    /**
     * 新增接龙计划预留名单
     * 
     * @param dto 接龙计划预留名单
     * @return 结果
     */
    @Override
    @Transactional
    public Long insertChainPlanReserveOrder(ChainPlanReserveOrder dto,Integer rowNum)
    {
        Map<String, SysDictData> vipMap = dictDataService.getDictData(DicType.DICT_TYPE_VIP_TYPE);
        if(!vipMap.containsKey(dto.getVipType())){
            throw new CustomException("VIP等级不存在");
        }
        dto.setVipTypeValue(vipMap.get(dto.getVipType()).getDictLabel());

        List<Chain> chains = chainMapper.selectList(Wrappers.<Chain>lambdaQuery().eq(Chain::getPlanId, dto.getPlanId()).eq(Chain::getDelFlag, "0"));
        if(CollectionUtil.isEmpty(chains)){
            throw new CustomException("该计划下不存在接龙链接");
        }

        Map<Long, Chain> chainGroup = chains.stream().collect(Collectors.toMap(
                Chain::getId,
                Function.identity(),
                (e, r) -> r
        ));

        // 校验品牌
        ChainPlan chainPlan = chainPlanMapper.selectById(dto.getPlanId());
        dto.setBrandId(chainPlan.getBrandId());
        if(!checkTbUserIdAndWdtId(dto)){
            throw new CustomException("淘宝账号和旺店通加密ID不匹配");
        }

        List<Long> chainIds = chains.stream().map(Chain::getId).collect(Collectors.toList());
        List<ChainDetail> chainDetails = chainDetailMapper.selectList(Wrappers.<ChainDetail>lambdaQuery().in(ChainDetail::getChainId, chainIds).eq(ChainDetail::getDelFlag, "0"));
        if(CollectionUtil.isEmpty(chainDetails)){
            throw new CustomException("该计划下不存在接龙商家编码");
        }

        Map<String, ChainDetail> chainDetailGroup = chainDetails.stream().collect(Collectors.toMap(
                ChainDetail::getSkuCode,
                Function.identity(),
                (e, r) -> r
        ));
        if(!chainDetailGroup.containsKey(dto.getSkuCode())){
            throw new CustomException(getRowError(rowNum)+ "该计划下不存在接龙商家编码:"+ dto.getSkuCode());
        }
        ChainDetail chainDetail = chainDetailGroup.get(dto.getSkuCode());
        dto.setSpuName( chainGroup.get(chainDetail.getChainId()).getName() + "-"+ chainDetail.getSpuName());
        dto.setSpecification(StringUtils.trim(chainDetail.getColor()) + StringUtils.trim(chainDetail.getSize()));

        List<ChainPlanReserveOrder> chainPlanReserveOrders = chainPlanReserveOrderMapper.selectList(Wrappers.<ChainPlanReserveOrder>lambdaQuery()
                .eq(ChainPlanReserveOrder::getSkuCode, dto.getSkuCode())
                .eq(ChainPlanReserveOrder::getPlanId, dto.getPlanId()).and(
                        wrapper -> wrapper.eq(ChainPlanReserveOrder::getTbUserId, dto.getTbUserId())
                                .or().eq(ChainPlanReserveOrder::getWdtEncodeUserId, dto.getWdtEncodeUserId())
                ).eq(ChainPlanReserveOrder::getDelFlag, "0")
        );

        if(CollectionUtil.isNotEmpty(chainPlanReserveOrders)){
            throw new CustomException(getRowError(rowNum) + "该计划下已经存在相同的订单信息:"+ dto.getSkuCode());
        }
        dto.setCreateTime(DateUtils.getNowDate());
        chainPlanReserveOrderMapper.insert(dto);

        return dto.getId();
    }

    private String getRowError(Integer rowNum) {
        return Objects.isNull(rowNum)? "" : "第"+rowNum+"行:";
    }

    /**
     * 修改接龙计划预留名单
     * 
     * @param dto 接龙计划预留名单
     * @return 结果
     */
    @Override
    @Transactional
    public int updateChainPlanReserveOrder(ChainPlanReserveOrder dto)
    {

        Map<String, SysDictData> vipMap = dictDataService.getDictData(DicType.DICT_TYPE_VIP_TYPE);
        if(!vipMap.containsKey(dto.getVipType())){
            throw new CustomException("VIP等级不存在");
        }
        dto.setVipTypeValue(vipMap.get(dto.getVipType()).getDictLabel());
        List<ChainPlanReserveOrder> dbOrders = chainPlanReserveOrderMapper.selectList(Wrappers.<ChainPlanReserveOrder>lambdaQuery()
                .eq(ChainPlanReserveOrder::getSkuCode, dto.getSkuCode())
                .eq(ChainPlanReserveOrder::getPlanId, dto.getPlanId()).and(
                        wrapper -> wrapper.eq(ChainPlanReserveOrder::getTbUserId, dto.getTbUserId())
                                .or().eq(ChainPlanReserveOrder::getWdtEncodeUserId, dto.getWdtEncodeUserId())
                ).eq(ChainPlanReserveOrder::getDelFlag, "0")
        );

        if (CollectionUtil.isNotEmpty(dbOrders) && !dbOrders.isEmpty()){
            dbOrders = dbOrders.stream().filter(dbOrder -> !dbOrder.getId().equals(dto.getId())).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(dbOrders)){
                throw new CustomException("该计划下已经存在相同的订单信息");
            }
        }
        ChainPlan chainPlan = chainPlanMapper.selectById(dto.getPlanId());
        dto.setBrandId(chainPlan.getBrandId());
        if(!checkTbUserIdAndWdtId(dto)){
            throw new CustomException("淘宝账号和旺店通加密ID不匹配");
        }

        ChainDetail detail = chainService.detail(chainPlan.getId(), dto.getSkuCode());
        if(Objects.isNull(detail)){
            throw new CustomException("【"+dto.getSkuCode() + "】不在本次接龙计划里面，请确认。" );
        }
        dto.setSpuName( detail.getSpuName());
        dto.setSpecification(StringUtils.trim(detail.getColor()) + StringUtils.trim(detail.getSize()));
        dto.setUpdateTime(DateUtils.getNowDate());
        return chainPlanReserveOrderMapper.updateChainPlanReserveOrder(dto);
    }

    /**
     * 批量删除接龙计划预留名单
     * 
     * @param ids 需要删除的接龙计划预留名单ID
     * @return 结果
     */
    @Override
    public int deleteChainPlanReserveOrderByIds(Long[] ids)
    {
        return chainPlanReserveOrderMapper.deleteChainPlanReserveOrderByIds(ids);
    }

    /**
     * 删除接龙计划预留名单信息
     * 
     * @param id 接龙计划预留名单ID
     * @return 结果
     */
    @Override
    public int deleteChainPlanReserveOrderById(Long id)
    {
        return chainPlanReserveOrderMapper.deleteChainPlanReserveOrderById(id);
    }


}
